package com.hw.service.order;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hw.entity.dto.order.OrderDTO;
import com.hw.entity.dto.order.OrderHistoryDTO;
import com.hw.entity.po.basic.Food;
import com.hw.entity.po.basic.StoreInfo;
import com.hw.entity.po.order.Order;
import com.hw.entity.po.shoppingCart.ShoppingCart;
import com.hw.entity.po.sys.SysUser;
import com.hw.entity.po.task.Task;
import com.hw.entity.query.order.HistoryOrderQuery;
import com.hw.entity.query.order.OrderQuery;
import com.hw.entity.vo.order.*;
import com.hw.mapper.order.OrderMapper;
import com.hw.mapper.shoppingCart.ShoppingCartMapper;
import com.hw.model.ResponseResult;
import com.hw.service.basic.FoodService;
import com.hw.service.basic.StoreInfoService;
import com.hw.service.shoppingCart.ShoppingCartService;
import com.hw.service.sys.SysUserService;
import com.hw.service.task.TaskService;
import com.hw.utils.AdminUtils;
import com.sun.org.apache.xpath.internal.operations.Or;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 订单表 Service实现类
 *
 * @author xuguang
 * @date 2021-06-28
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private FoodService foodService;

    @Autowired
    private StoreInfoService storeInfoService;

    @Autowired
    private TaskService taskService;

    @Autowired
    @Lazy(true)
    private ShoppingCartService shoppingCartService;

    @Autowired
    private ShoppingCartMapper shoppingCartMapper;


    /**
     * 获取以菜品为单位的用户信息
     *
     * @param taskId
     * @return
     */
    @Override
    public List<OrderVO> getUserAndFoodByOrder(String taskId) {
        List<OrderVO> orderVOS = new LinkedList<>();

        // 获取查询得到的数据
        List<TempVO> tempVOs = baseMapper.getUserAndFoodByOrder(taskId);

        boolean isEqual = false;
        // 将接收到的数据 tempVOs 按照一定的格式转到orderVOS去，方便输出
        for (TempVO tempVO : tempVOs) {
            // 以菜品为单位循环，跟要返回的集合对比
                // 1、名称不同  =>  转移所有信息，是orderVOS集合里面新的元素
                // 2、名称相同  =>  查找到对应的元素，①将number属性求和，②将头像信息存入该元素的userAvatarVOs集合里
            for (OrderVO orderVO : orderVOS) {
                // 若相等，这个orderVO就是对应的元素，更新
                if (orderVO.getFoodName().equals(tempVO.getFoodName())) {
                    // 用户信息必须存入
                    UserAvatarVO userAvatarVO = new UserAvatarVO();
                    // 头像存入
//                    if (ObjectUtils.isNotEmpty(tempVO.getUserAvatar())) {
//                        String avatarBase64 = ImgUtil.toBase64(ImgUtil.toImage(tempVO.getUserAvatar()), "png");
//                        userAvatarVO.setUserAvatarVO(avatarBase64);
//                        userAvatarVO.setUserAvatar(null);
//                    }
                    BeanUtils.copyProperties(tempVO, userAvatarVO);
                    // 判断重复元素，如果已存在则不加入(此处重写了UserAvatarVO类的equals方法：只要昵称相同，则返回true,避免备注不同而添加相同昵称的vo)
                    if (!orderVO.getUserAvatarVOS().contains(userAvatarVO)) {
                        orderVO.getUserAvatarVOS().add(userAvatarVO);
                    }
                    // 更新总价格
                    orderVO.setPrice(orderVO.getPrice() + tempVO.getPrice());
                    // 更新总数量
                    orderVO.setNumber(orderVO.getNumber() + tempVO.getNumber());
                    isEqual = true;
                }
            }
            // 循环出来之后，用isEqual判断是否已经为这条tempVO进行了添加
            if (isEqual) {
                // 已添加，则重新将isEqual设置为false，便于下次使用
                isEqual = false;
            } else {
                // 否则说明这一条数据还没添加，则进行新的元素添加
                OrderVO orderVO = new OrderVO();
                BeanUtils.copyProperties(tempVO, orderVO);
//                orderVO.setFoodImg(tempVO.getFoodImg());
                // 头像，名称和备注信息添加
                List<UserAvatarVO> userAvatarVOS = new LinkedList<>();
                UserAvatarVO userAvatarVO = new UserAvatarVO();
//                if (ObjectUtils.isNotEmpty(tempVO.getUserAvatar())) {
//                    String avatarBase64 = ImgUtil.toBase64(ImgUtil.toImage(tempVO.getUserAvatar()), "png");
//                    userAvatarVO.setUserAvatarVO(avatarBase64);
//                }
                BeanUtils.copyProperties(tempVO, userAvatarVO);
                userAvatarVOS.add(userAvatarVO);
                orderVO.setUserAvatarVOS(userAvatarVOS);

                // 第一次添加需要处理图片
                // 菜品图片存入
//                if (ObjectUtils.isNotEmpty(tempVO.getFoodImg())) {
//                    String avatarBase64 = ImgUtil.toBase64(ImgUtil.toImage(tempVO.getFoodImg()), "png");
//                    orderVO.setFoodImgVO(avatarBase64);
//                }
                orderVOS.add(orderVO);
            }
        }
        return orderVOS;
    }

    /**
     * 获取当前用户的历史订单
     *
     * @param orderQuery
     * @return
     */
    @Override
    public IPage<OrderListVO> getList(OrderQuery orderQuery) {
        // 获取当前用户
        SysUser currentUser = sysUserService.getOne(AdminUtils.getUserName());

        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        // 查看自己的历史记录
        queryWrapper
                .eq("o.c_user_id", currentUser.getUserId())
                .eq("o.c_deleted", 0);
        if (orderQuery.getTime() != null) {
            // 处理时间格式
            orderQuery.setTime(orderQuery.getTime().plusHours(8));
            LocalDateTime dateNight = orderQuery.getTime();
            dateNight = dateNight.plusHours(23).plusMinutes(59).plusSeconds(59);
            queryWrapper
                    .ge("t.c_create_time", orderQuery.getTime())
                    .le("t.c_end_time", dateNight);
        }
        if (orderQuery.getStoreId() != null && orderQuery.getStoreId() != "") {
            queryWrapper
                    .eq("s.c_store_id", orderQuery.getStoreId());
        }
        Page<OrderListVO> page = new Page<>(orderQuery.getPageIndex(), orderQuery.getPageSize());

        IPage<OrderListVO> list = baseMapper.getList(page, queryWrapper);
//        if (list == null) {
//            return null;
//        }

        // 循环设置 查询得到的总价，菜品数量和设置最新的状态
        for (OrderListVO record : list.getRecords()) {
            record.setFoodPrice(getTotalPrice(record.getTaskId()));
            record.setFoodNumber(getTotalNumber(record.getTaskId()));
            record.setStatus(getTaskStatus(record.getTaskId()));
        }
        return list;
    }

    /**
     * 生成订单
     *
     * @param orderDTOS
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public ResponseResult<?> saveOrder(List<OrderDTO> orderDTOS) {
        if (orderDTOS == null) {
            return ResponseResult.error("已点列表为空，不能保存!");
        }
        // 获取当前用户
        SysUser currentUser = sysUserService.getOne(AdminUtils.getUserName());

        // 暴力删除当前订单id当前用户所有的订单
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("c_user_id", currentUser.getUserId())
                .eq("c_task_id", orderDTOS.get(0).getTaskId());
        remove(queryWrapper);

        // 重新添加
        for (OrderDTO dto : orderDTOS) {
            Order po = new Order();
            if (ObjectUtils.isNotEmpty(dto)) {
                BeanUtils.copyProperties(dto, po);
                // 通过菜品id获取菜品，更新累计被点单数
                Food tempFood = foodService.getOne(new QueryWrapper<Food>()
                        .eq("c_food_id", po.getFoodId())
                        .eq("c_deleted", 0));
                tempFood.setCount(tempFood.getCount() + 1);
                foodService.updateById(tempFood);

                LocalDateTime now = LocalDateTime.now();

                // 以下是字段名不一致或需要手动加入的
                po.setRemark(dto.getFoodRemark());
                po.setOrderId(UUID.randomUUID().toString());
                po.setUserId(currentUser.getUserId());
                po.setPrice(dto.getSinglePrice() * dto.getNumber());
                po.setTitle(now.getYear() + "年" + now.getMonthValue() + "月" + now.getDayOfMonth() + "日 点餐");
            }
            baseMapper.insert(po);
        }
        // 通过任务码查询商家，更新一次商家的累计被点单数
        Task tempTask = taskService.getOne(new QueryWrapper<Task>()
                .eq("c_task_id", orderDTOS.get(0).getTaskId())
                .eq("c_deleted", 0));
        StoreInfo tempStore = storeInfoService.getOne(new QueryWrapper<StoreInfo>()
                .eq("c_store_id", tempTask.getStoreId())
                .eq("c_deleted", 0));
        tempStore.setCount(tempStore.getCount() + 1);
        storeInfoService.updateById(tempStore);
        return ResponseResult.success();
    }


    /**
     * 获取历史点餐详情(查询自己的)
     *
     * @param historyOrderQuery
     * @return
     */
    @Override
    public List<HistoryOrderVO> getHistoryInfo(HistoryOrderQuery historyOrderQuery) {
        SysUser currentUser = sysUserService.getOne(AdminUtils.getUserName());
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("o.c_deleted", 0)
                .eq("o.c_user_id", currentUser.getUserId())
                .eq("o.c_task_id", historyOrderQuery.getTaskId());
        return baseMapper.getHistoryInfo(queryWrapper);
    }

    /**
     * 获取当前用户当前订单id的总价格
     *
     * @param taskId
     * @return
     */
    @Override
    public Double getTotalPrice(String taskId) {
        SysUser currentUser = sysUserService.getOne(AdminUtils.getUserName());
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("c_deleted", 0)
                .eq("c_task_id", taskId)
                .eq("c_user_id", currentUser.getUserId());
        return baseMapper.getTotalPrice(queryWrapper);
    }

    /**
     * 获取当前用户当前订单id的菜品总数量
     *
     * @param taskId
     * @return
     */
    @Override
    public Integer getTotalNumber(String taskId) {
        SysUser currentUser = sysUserService.getOne(AdminUtils.getUserName());
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("c_deleted", 0)
                .eq("c_task_id", taskId)
                .eq("c_user_id", currentUser.getUserId());
        return baseMapper.getTotalNumber(queryWrapper);
    }

    /**
     * 内部方法，查询并更新点餐订单状态，并返回最新的点餐状态
     * @param taskId
     * @return
     */
    private Integer getTaskStatus(String taskId) {
        QueryWrapper<Task> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("c_deleted", 0)
                .eq("c_task_id", taskId);
        Task task = taskService.getOne(queryWrapper);
        if (task.getEndTime().isBefore(LocalDateTime.now()) && task.getStatus() == 0) {
            task.setStatus(1);
            taskService.updateById(task);
            return 1;
        }
        if (task.getStatus() == 1) {
            return 1;
        }
       return 0;
    }

    /**
     * 保存历史详情更改
     *
     * @param orderHistoryDTOS
     * @return
     */
    @Override
    public ResponseResult<?> saveHistoryChange(List<OrderHistoryDTO> orderHistoryDTOS) {
        SysUser currentUser = sysUserService.getOne(AdminUtils.getUserName());
        // order表根据订单id遍历查询并更新数量、备注和单菜品总价格
        // 购物车表根据菜品id和用户id查询并更新数量、备注和单菜品总价格
        for (OrderHistoryDTO dto : orderHistoryDTOS) {
            QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
            orderQueryWrapper.eq("c_order_id", dto.getOrderId());
            Order orderPO = baseMapper.selectOne(orderQueryWrapper);
            if (orderPO == null) {
                return ResponseResult.success("订单不存在该信息!");
            }
            BeanUtils.copyProperties(dto, orderPO);
            baseMapper.updateById(orderPO);

            QueryWrapper<ShoppingCart> shoppingCartQueryWrapper = new QueryWrapper<>();
            shoppingCartQueryWrapper
                    .eq("c_food_id", dto.getFoodId())
                    .eq("c_user_id", currentUser.getUserId())
                    .eq("c_task_id", dto.getTaskId());
            ShoppingCart shoppingCartPO = shoppingCartService.getOne(shoppingCartQueryWrapper);

            if (shoppingCartPO == null) {
                return ResponseResult.success("已点列表没有该信息!");
            }

            // 不能用这个，数据库改变不了值
//            BeanUtils.copyProperties(dto, shoppingCartPO);
            shoppingCartPO.setRemark(dto.getRemark());
            shoppingCartPO.setNumber(dto.getNumber());
            shoppingCartPO.setPrice(dto.getPrice());
            shoppingCartMapper.updateById(shoppingCartPO);
        }
        return ResponseResult.success();
    }

}
